<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="mwL0y" id="mwL0y"><span data-lake-id="ucaada814" id="ucaada814">典型回答</span></h1>
  <p data-lake-id="u3222396d" id="u3222396d"><br></p>
  <p data-lake-id="uc682add8" id="uc682add8"><br></p>
  <p data-lake-id="u37466e11" id="u37466e11"><strong><span data-lake-id="ubbd9355d" id="ubbd9355d">首先，Spring的AOP其实是通过动态代理实现的，所以，想要让AOP生效，前提必须是动态代理生效，并且可以调用到代理对象的方法。</span></strong></p>
  <p data-lake-id="uec9d2777" id="uec9d2777"><span data-lake-id="u8cc863ff" id="u8cc863ff">​</span><br></p>
  <p data-lake-id="u2ea90792" id="u2ea90792"><span data-lake-id="uf30aa7bf" id="uf30aa7bf">什么情况下会不走代理对象的调用呢？</span></p>
  <p data-lake-id="u90602e13" id="u90602e13"><span data-lake-id="uff3eb263" id="uff3eb263">​</span><br></p>
  <p data-lake-id="ue77f88e8" id="ue77f88e8"><span data-lake-id="u510f6d3b" id="u510f6d3b">首先就是类内部的调用，比如一些私有方法调用，内部类调用，以及同一个类中方法的自调用等。如：</span></p>
  <p data-lake-id="ua3d85b86" id="ua3d85b86"><span data-lake-id="ud505fbf9" id="ud505fbf9">​</span><br></p>
  <pre lang="java"><code>
//1
public class MyService {
    public void doSomething() {
        doInternal(); // 自调用方法
    }

    public void doInternal() {
        System.out.println("Doing internal work...");
    }
}

//2
public class MyService {
    public void doSomething() {
        doInternal(); // 自调用私有方法
    }

    private void doInternal() {
        System.out.println("Doing internal work...");
    }
}


//3
public class OuterClass {
    private class InnerClass {
        public void doSomething() {
            System.out.println("Doing something in inner class...");
        }
    }

    public void invokeInnerClassMethod() {
        InnerClass innerClass = new InnerClass();
        innerClass.doSomething(); // 调用内部类方法
    }
}
</code></pre>
  <p data-lake-id="uc389e533" id="uc389e533"><br></p>
  <p data-lake-id="uc30730f7" id="uc30730f7"><span data-lake-id="uedf9bb05" id="uedf9bb05">以上，都是因为在对象内部直接调用其他方法，就会用原始对象直接调用了，不会调用到代理对象，所以代理会失效。</span></p>
  <p data-lake-id="u6fb5673a" id="u6fb5673a"><span data-lake-id="u90913f49" id="u90913f49">​</span><br></p>
  <p data-lake-id="ufa95bc8c" id="ufa95bc8c"><strong><span data-lake-id="uf1b93e7d" id="uf1b93e7d">类似的还有一种情况，虽然不是对象的自调用，但是他也是因为没有调用到代理对象，那就是调用static方法，因为这类方法是属于这个类的，并不是对象的，所以无法被AOP。</span></strong></p>
  <p data-lake-id="u210135b1" id="u210135b1"><strong><span data-lake-id="ua57e8d74" id="ua57e8d74">​</span></strong><br></p>
  <pre lang="java"><code>
public class MyService {
    public staic void doSomething() {
        // static 方法
    }
}
</code></pre>
  <p data-lake-id="u27dc8d0a" id="u27dc8d0a"><span data-lake-id="uc6e59223" id="uc6e59223">​</span><br></p>
  <p data-lake-id="uea092d07" id="uea092d07"><strong><span data-lake-id="u9cb70a78" id="u9cb70a78">还有一种方法，也无法被代理，那就是final方法，由于AOP是通过创建代理对象来实现的，而无法对final方法进行子类化和覆盖，所以无法拦截这些方法。</span></strong></p>
  <p data-lake-id="ueecea0c5" id="ueecea0c5"><span data-lake-id="u66e93c45" id="u66e93c45">​</span><br></p>
  <pre lang="java"><code>
public class MyService {
    public final void doSomethingFinal() {
        System.out.println("Doing something final...");
    }
}
</code></pre>
  <p data-lake-id="ue4eb6ed9" id="ue4eb6ed9"><br></p>
  <p data-lake-id="udc0b14fc" id="udc0b14fc"><br></p>
  <p data-lake-id="ud70f9b6d" id="ud70f9b6d"><span data-lake-id="ufa6bf508" id="ufa6bf508">所以，那么总结一下就是以下几种情况，会导致代理失效，AOP不起作用：</span></p>
  <p data-lake-id="uad60fa3b" id="uad60fa3b"><span data-lake-id="uefbfdd10" id="uefbfdd10">​</span><br></p>
  <p data-lake-id="u8800b729" id="u8800b729"><span data-lake-id="ub50407bf" id="ub50407bf">1、私有方法调用</span></p>
  <p data-lake-id="uce4c4eae" id="uce4c4eae"><span data-lake-id="u6778baa0" id="u6778baa0">2、静态方法调用</span></p>
  <p data-lake-id="uda36e88b" id="uda36e88b"><span data-lake-id="uea4dc3bd" id="uea4dc3bd">3、final方法调用</span></p>
  <p data-lake-id="u93dab259" id="u93dab259"><span data-lake-id="u3a867f3b" id="u3a867f3b">4、类内部自调用</span></p>
  <p data-lake-id="u1dce6a69" id="u1dce6a69"><span data-lake-id="u7a5b35c7" id="u7a5b35c7">5、内部类方法调用</span></p>
 </body>
</html>